package cn.com.anypay.manager.controller.pay;

import cn.com.anypay.manager.common.utils.AnyJsonUtils;
import cn.com.anypay.manager.dto.config.payment.WxAppConfig;
import cn.com.anypay.manager.dto.config.payment.WxpayServiceProviderConfig;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.Base64;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RestController
@RequestMapping("/api/isv/wxpay")
public class IsvWxpayController {
    private static final Logger log = LoggerFactory.getLogger(IsvWxpayController.class);

    @Autowired
    @Qualifier("wxPayMiniappConfig")
    private WxAppConfig miniappConfig;

    @Autowired
    @Qualifier("wxPayMpConfig")
    private WxAppConfig mpConfig;

    @Autowired
    @Qualifier("wxPayServiceProviderConfig")
    private WxpayServiceProviderConfig serviceProviderConfig;

    @Autowired
    private RestTemplate restTemplate;

    // 创建特约商户支付订单
    @PostMapping("/v1/payments")
    public Map<String, Object> createPayment(@RequestBody Map<String, Object> params) {
        try {
            log.info("=== 创建特约商户支付订单开始 ===");
            log.info("请求参数: {}", params);

            // 1. 参数验证
            String orderNo = (String) params.get("orderNo");
            log.info("服务商配置: {}", serviceProviderConfig);
            log.info("特约商户配置: {}", serviceProviderConfig.getSubMerchants());
            if (!serviceProviderConfig.getSubMerchants().containsKey("mch1")) {
                return Map.of(
                    "code", -1,
                    "message", "无效的特约商户配置"
                );
            }
            String subMchId = serviceProviderConfig.getSubMerchants().get("mch1").getMchId(); // 从配置中读取特约商户号
            log.info("特约商户号: {}", subMchId);
            Double amount = ((Number) params.get("amount")).doubleValue();
            String description = (String) params.get("description");
            String openId = (String) params.get("openId");

            // 2. 生成订单号
            orderNo = String.format("ORDER_%d_%s",
                System.currentTimeMillis(),
                UUID.randomUUID().toString().replace("-", "").substring(0, 8)
            );

            // 3. 调用微信统一下单
            String url = serviceProviderConfig.getDomain() + "/v3/pay/partner/transactions/jsapi";
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("sp_appid", mpConfig.getAppId());
            requestBody.put("sp_mchid", serviceProviderConfig.getMchId());
            requestBody.put("sub_mchid", subMchId);
            requestBody.put("description", description);
            requestBody.put("out_trade_no", orderNo);
            requestBody.put("notify_url", serviceProviderConfig.getNotifyUrl() + "/api/pay/notify/wechat-isv");

            Map<String, Object> amountInfo = new HashMap<>();
            amountInfo.put("total", (int)(amount * 100));
            amountInfo.put("currency", "CNY");
            requestBody.put("amount", amountInfo);

            Map<String, Object> payer = new HashMap<>();
            payer.put("sp_openid", openId);
            requestBody.put("payer", payer);

            // 4. 生成认证头
            String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
            String nonce = UUID.randomUUID().toString().replace("-", "");
            String message = "POST\n/v3/pay/partner/transactions/jsapi\n" + timestamp + "\n" + nonce + "\n" + AnyJsonUtils.toJsonString(requestBody) + "\n";
            String signature = generateRSASign(message);

            // 5. 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Accept", "application/json");
            headers.set("Authorization", "WECHATPAY2-SHA256-RSA2048 " + String.format("mchid=\"%s\",nonce_str=\"%s\",timestamp=\"%s\",serial_no=\"%s\",signature=\"%s\"",
                serviceProviderConfig.getMchId(),
                nonce,
                timestamp,
                serviceProviderConfig.getMchSerialNo(),
                signature
            ));

            // 6. 发送请求
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
            ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
            String response = responseEntity.getBody();
            log.info("统一下单响应: {}", response);

            // 7. 解析响应
            Map<String, Object> result = AnyJsonUtils.toMap(response);

            // 8. 生成支付参数
            Map<String, String> payParams = new HashMap<>();
            payParams.put("appId", mpConfig.getAppId());
            payParams.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
            payParams.put("nonceStr", UUID.randomUUID().toString().replace("-", ""));
            payParams.put("package", "prepay_id=" + result.get("prepay_id"));
            payParams.put("signType", "RSA");

            // 9. 生成签名
            String signStr = String.format("%s\n%s\n%s\n%s\n",
                payParams.get("appId"),
                payParams.get("timeStamp"),
                payParams.get("nonceStr"),
                payParams.get("package")
            );

            String paySign = generateRSASign(signStr);
            payParams.put("paySign", paySign);

            return Map.of(
                "code", 0,
                "message", "success",
                "data", Map.of(
                    "orderNo", orderNo,
                    "payParams", payParams
                )
            );
        } catch (Exception e) {
            log.error("创建特约商户支付订单失败: {}", e.getMessage(), e);
            return Map.of(
                "code", -1,
                "message", "创建特约商户支付订单失败: " + e.getMessage()
            );
        }
    }

    // RSA签名工具方法
    private String generateRSASign(String message) throws Exception {
        String privateKeyPath = serviceProviderConfig.getPrivateKeyPath();
        String privateKey = new String(java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(privateKeyPath)));

        privateKey = privateKey.replace("-----BEGIN PRIVATE KEY-----", "")
                             .replace("-----END PRIVATE KEY-----", "")
                             .replaceAll("\\s+", "");

        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKey);
        java.security.spec.PKCS8EncodedKeySpec keySpec = new java.security.spec.PKCS8EncodedKeySpec(privateKeyBytes);
        java.security.KeyFactory keyFactory = java.security.KeyFactory.getInstance("RSA");
        java.security.PrivateKey rsaPrivateKey = keyFactory.generatePrivate(keySpec);

        java.security.Signature signature = java.security.Signature.getInstance("SHA256withRSA");
        signature.initSign(rsaPrivateKey);
        signature.update(message.getBytes(StandardCharsets.UTF_8));

        return Base64.getEncoder().encodeToString(signature.sign());
    }
}